package com.zhenzhang.myblog.utils;

import com.zhenzhang.myblog.entity.role.ACCEPT_AVATAR_TYPE;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.ResponseEntity;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class FileUtils {

    private static final HashMap<String,String> map = new HashMap<>();
    static {
        // 一般网页资源
        map.put("html", "text/html;charset=utf-8");
        map.put("htm", "text/html;charset=utf-8");
        map.put("js", "application/x-javascript;charset=utf-8");
        map.put("css", "text/css;charset=utf-8");
        map.put("txt", "text/plain;charset=utf-8");

        // 图片
        map.put("gif", "image/gif");
        map.put("jpg", "image/jpeg");
        map.put("jpeg", "image/jpeg");
        map.put("png", "image/png");
        map.put("ico", "image/x-icon");

        // 音乐
        map.put("mp3", "audio/mp3");
        map.put("mp2", "audio/mp2");
        map.put("ogg", "audio/ogg");
        map.put("ape", "audio/ape");
        map.put("flac", "audio/flac");

        // 视频
        map.put("mp4", "video/mp4");

        // 视频
        map.put("pdf", "application/pdf");
    }

    /**
     * 获取文件名中的后缀名，即最后一个字符'.'后面的子字符串，若无后缀名，则返回整个原文件名
     * @param name  文件名或文件路径
     * @return  后缀名，不带'.'
     */
    public static String getSuffix(String name) {
        String[] split = name.split("\\.");
        if (split.length != 0) {
            return split[split.length - 1].toLowerCase();
        } else {
            return name;
        }
    }

    /**
     * 判断后缀名是否含于头像文件类型枚举类
     * @param suffix 后缀名
     * @return  判断结果布尔值
     */
    public static boolean contain(String suffix) {
        for(ACCEPT_AVATAR_TYPE type : ACCEPT_AVATAR_TYPE.values()) {
            if(type.getType().equals(suffix)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 通过文件名获取对应文件类型的Content-Type
     * @param name  文件名
     * @return Content-Type结果
     */
    static public String getContentType(String name) {
        name = getSuffix(name);
        String res = map.get(name);
        return res == null ? "application/octet-stream" : res;
    }

    /**
     * 获取本地文件的资源响应体
     * @param localFilePath     本地文件路径
     * @param name              文件响应重命名
     * @return  响应实体
     */
    public static ResponseEntity<Resource> getFileResponseEntity(String localFilePath, String name) throws MalformedURLException, UnsupportedEncodingException {
        Path path = Paths.get(localFilePath);
        if (Files.isDirectory(path)) {
            throw new IllegalArgumentException("无法直接下载文件夹");
        }
        UrlResource urlResource = new UrlResource(path.toUri());
        return getFileResponseEntity(urlResource, name);
    }
    /**
     * 获取资源响应体
     * @param resource 要响应的资源
     * @param name 响应文件重命名
     * @return  响应实体
     */
    public static ResponseEntity<Resource> getFileResponseEntity(Resource resource, String name) {
        String disposition = "inline;filename*=UTF-8''"+ URLEncoder.encode(name, StandardCharsets.UTF_8);
        return ResponseEntity.ok()
                .header("Content-Type", FileUtils.getContentType(name))
                .header("Content-Disposition", disposition)
                .body(resource);
    }

    /**
     * 获取资源响应体
     * @param resource 要响应的资源
     * @return  响应实体
     */
    public static ResponseEntity<Resource> getFileResponseEntity(Resource resource) {
        return getFileResponseEntity(resource, resource.getFilename());
    }

    /**
     * 获取本地文件的资源响应体
     * @param localFilePath     本地文件路径
     * @return  响应实体
     */
    public static ResponseEntity<Resource> getFileResponseEntity(String localFilePath) throws MalformedURLException, UnsupportedEncodingException {
        Path path = Paths.get(localFilePath);
        return getFileResponseEntity(localFilePath, path.getFileName().toString());
    }

    /**
     * 获取文件夹中所有文件的文件列表
     * @param path  路径
     */
    public static List<File> getFilesFromDir(String path) {
        File[] allFiles = new File(path).listFiles();
        List<File> fileList = new ArrayList<>();
        if (allFiles == null) {
            return fileList;
        }
        for (File file : allFiles) {
            if (file.isFile()) {
                fileList.add(file);
            } else {
                getFilesFromDir(file.getAbsolutePath());
            }
        }
        return fileList;
    }
}
